package com.zrwl.poscloud.commons.utils;

import com.zrwl.poscloud.base.entity.Employee;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class EmployeeUtil {
    public EmployeeUtil() {
        throw new Error("工具类不允许实例化！");
    }
    /**
     * 身份证号最大长度
     */
    private static final int ID_CARD_NUMBER_MAX_LENGTH = 18;

    /**
     * 身份证号最小长度
     */
    private static final int ID_CARD_NUMBER_MIN_LENGTH = 15;

    /**
     * 加权因子
     */
    private static final int[] WEIGHT_FACTOR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    /**
     * 校验码
     */
    private static final String[] CHECK_CODE = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

    /**
     * 省（直辖市、自治区）的代码
     */
    private static final String[] CITY_CODE = {"11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41",
            "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71",
            "81", "82", "91"};
    /**
     * 是否不是身份证号
     *
     * @param idCard 身份证号
     * @return true不是 false是
     */
    public static boolean isNotIdCard(String idCard) {

        log.info("idCard-->{}", idCard);

        if (StringUtils.isEmpty(idCard)) {
            return true;
        }

        idCard = idCard.toUpperCase();

        if (idCard.length() == ID_CARD_NUMBER_MIN_LENGTH) {
            idCard = idCardFrom15To18(idCard);
        }

        if (idCard.length() == ID_CARD_NUMBER_MAX_LENGTH) {

            if (isNotAllNumber(idCard)) {
                return true;
            }

            if (isNotCityCode(idCard)) {
                return true;
            }
            String lastOneNum = idCard.substring(idCard.length() - 1);
            String countLastOneNum = countIdCardLastOneNum(idCard.substring(0, idCard.length() - 1));
            return !lastOneNum.equals(countLastOneNum);
        }

        return true;
    }
    /**
     * 根据身份证号获取身份证信息
     *
     * @param idCard 身份证号
     * @return 身份证信息
     */
    public static Employee getIdCardInfo(String idCard) {
        if (isNotIdCard(idCard)) {
            return null;
        }

        idCard = idCard.toUpperCase();

        if (idCard.length() == ID_CARD_NUMBER_MIN_LENGTH) {
            idCard = idCardFrom15To18(idCard);
        }

        Employee employee = new Employee();
        employee.setCertCode(idCard);
        employee.setSex(Integer.parseInt(getSexCode(idCard)));
        //employee.setSex(getSex(idCardInfo.getSexCode()));性别
        //employee.setBirthStr(getBirthStr(idCard));出生体重
        employee.setBirthday(getBirth(getBirthStr(idCard)));
        //idCardInfo.setAge(getAge(idCardInfo.getBirth()));年龄
        return employee;
    }
    /**
     * 15位身份证号转18位身份证号
     *
     * @param idCard 15位身份证号
     * @return 18位身份证
     */
    public static String idCardFrom15To18(String idCard) {
        String prefix = "19";
        StringBuilder sb = new StringBuilder(idCard);
        sb.insert(6, prefix);
        sb.append(countIdCardLastOneNum(sb.toString()));
        return sb.toString();
    }
    /**
     * 计算17身份证号最后一位数
     *
     * @param idCard 身份证号
     * @return 最后一位身份证号
     */
    private static String countIdCardLastOneNum(String idCard) {
        StringBuilder sb = new StringBuilder(idCard);
        int sum = 0;
        int size = sb.length();
        for (int i = 0; i < size; i++) {
            sum += (Integer.parseInt(sb.substring(i, i + 1)) * WEIGHT_FACTOR[i]);
        }
        int divisor = 11;
        return (CHECK_CODE[sum % divisor]);
    }
    /**
     * 身份证不是纯数字（18位，前17位都是数字）
     *
     * @param idCard 身份证号
     * @return true不是 false是
     */
    private static boolean isNotAllNumber(String idCard) {
        Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
        Matcher matcher = pattern.matcher(idCard.substring(0, 17));
        return !matcher.matches();
    }
    /**
     * 检查不是省（直辖市、自治区）的代码
     *
     * @param idCard 身份证号
     * @return true不是 false是
     */
    private static boolean isNotCityCode(String idCard) {
        int start = 0;
        int end = 2;
        int errorIndex = -1;
        return Arrays.binarySearch(CITY_CODE, idCard.substring(start, end)) == errorIndex;
    }
    /**
     * 根据身份证获取性别编码
     *
     * @param idCard 身份证号
     * @return 性别编码
     */
    public static String getSexCode(String idCard) {
        int sexCode = (Integer.parseInt(idCard.substring(16, idCard.length() - 1))) % 2;
        return (sexCode == 0) ? "2" : "1";
    }
    /**
     * 获取性别中文
     *
     * @param sexCode 性别编码
     * @return 性别中文
     */
    public static String getSex(String sexCode) {
        switch (sexCode) {
            case "1":
                return "男";
            case "2":
                return "女";
            default:
                return "未知";
        }
    }
    /**
     * 性别的有效性
     *
     * @param sex 性别
     * @param certCode 身份证号
     * @return 性别
     */
    public static boolean genderIsItEffective(String sex,String certCode) {
        return sex.equals(getSex(getSexCode(certCode)));
    }

    /**
     * 基于身份证获取性别
     * @param certCode 身份证号
     * @return 性别中文
     */
    public static String genderBasedOnCertCode(String certCode) {
        return getSex(getSexCode(certCode));
    }
    /**
     * 根据身份证号获取生日字符串
     *
     * @param idCard 身份证号
     * @return 生日字符串
     */
    private static String getBirthStr(String idCard) {
        int start = 6;
        int end = 14;
        StringBuilder sb = new StringBuilder(idCard.substring(start, end));
        int index = 4;
        char value = '-';
        sb.insert(index, value);
        index = 7;
        sb.insert(index, value);
        return sb.toString();
    }
    /**
     * 生日字符串转生日日期 （yyyy-MM-dd）
     *
     * @param birthStr 生日字符串
     * @return 生日日期
     */
    private static Date getBirth(String birthStr) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            format.setLenient(false);
            return format.parse(birthStr);
        } catch (Exception ex) {
            return null;
        }
    }
    /**
     * 生日的有效性
     *
     * @param birthday 生日
     * @param certCode 身份证号
     * @return 生日日期
     */
    public static boolean birthdayIsItEffective(String birthday,String certCode) {
            return getBirth(birthday).equals(getBirth(getBirthStr(certCode)));
    }
    /**
     * 基于身份证获取生日
     * @param certCode 身份证号
     * @return 生日日期
     */
    public static String birthdayBasedOnCertCode(String certCode) {
        return DateUtils.dateTimeToStr2(getBirth(getBirthStr(certCode)));
    }
    /**
     * 根据生日日期获取年龄
     *
     * @param birth 生日日期
     * @return 年龄
     */
    private static int getAge(Date birth) {
        Calendar certificateCal = Calendar.getInstance();
        Calendar currentTimeCal = Calendar.getInstance();
        certificateCal.setTime(birth);
        int yearAge = (currentTimeCal.get(Calendar.YEAR)) - (certificateCal.get(Calendar.YEAR));
        certificateCal.set(currentTimeCal.get(Calendar.YEAR), certificateCal.get(Calendar.MONTH), certificateCal.get(Calendar.DAY_OF_MONTH));
        int monthFloor = (currentTimeCal.before(certificateCal) ? 1 : 0);
        return (yearAge - monthFloor);
    }

}
